﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PersonalFinances.Models;
using PersonalFinances.ViewModels;

namespace PersonalFinances.Controllers
{
    public class TransactionsController : Controller
    {
        private TransactionDbContext _transactionDb = new TransactionDbContext();
        private AccountDbContext _accountDb = new AccountDbContext();
        private CategoryDbContext _categoryDb = new CategoryDbContext();

        //
        // GET: /Transactions/

        public ActionResult Index()
        {
            return View(_transactionDb.Transactions.ToList());
        }

        //
        // GET: /Transactions/Details/5

        public ActionResult Details(int id = 0)
        {
            Transaction transaction = _transactionDb.Transactions.Find(id);
            transaction.Account = _accountDb.Accounts.FirstOrDefault(a => a.ID == transaction.AccountID);
            transaction.Category = _categoryDb.Categories.FirstOrDefault(c => c.ID == transaction.CategoryID);
            if (transaction == null)
            {
                return HttpNotFound();
            }
            return View(transaction);
        }

        //
        // GET: /Transactions/Create

        public ActionResult Create()
        {
            return View(new TransactionCreateViewModel()
                {
                    Transaction = new Transaction(),
                    Accounts = _accountDb.Accounts.ToList(),
                    Categories = _categoryDb.Categories.ToList()
                });
        }

        //
        // POST: /Transactions/Create

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(TransactionCreateViewModel createViewModel)
        {
            createViewModel.Accounts = _accountDb.Accounts.ToList();
            createViewModel.Categories = _categoryDb.Categories.ToList();

            if (ModelState.IsValid)
            {
                Transaction transaction = createViewModel.Transaction;
                Account account = _accountDb.Accounts.Single(a => a.ID == transaction.AccountID);
                account.ApplyTransaction(transaction);
                _accountDb.SaveChanges();
                _transactionDb.Transactions.Add(transaction);
                _transactionDb.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(createViewModel);
        }

        //
        // GET: /Transactions/Edit/5

        public ActionResult Edit(int id = 0)
        {
            Transaction transaction = _transactionDb.Transactions.Find(id);
            if (transaction == null)
            {
                return HttpNotFound();
            }
            return View(new TransactionEditViewModel()
                {
                    Transaction = transaction,
                    Categories = _categoryDb.Categories.ToList(),
                    WasPaidTransaction = transaction.Paid
                });
        }

        //
        // POST: /Transactions/Edit/5

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(TransactionEditViewModel editViewModel)
        {
            if (ModelState.IsValid)
            {
                Transaction transaction = editViewModel.Transaction;
                Account account = _accountDb.Accounts.Single(a => a.ID == transaction.AccountID);
                if (!editViewModel.WasPaidTransaction && transaction.Paid)
                {
                    account.ApplyTransaction(transaction);
                    _accountDb.SaveChanges();
                }
                else if (editViewModel.WasPaidTransaction && !transaction.Paid)
                {
                    account.CancelTransaction(transaction);
                    _accountDb.SaveChanges();
                }
                _transactionDb.Entry(transaction).State = EntityState.Modified;
                _transactionDb.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(editViewModel);
        }

        //
        // GET: /Transactions/Delete/5

        public ActionResult Delete(int id = 0)
        {
            Transaction transaction = _transactionDb.Transactions.Find(id);
            if (transaction == null)
            {
                return HttpNotFound();
            }
            return View(transaction);
        }

        //
        // POST: /Transactions/Delete/5

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Transaction transaction = _transactionDb.Transactions.Find(id);

            Account account = transaction.Account;
            account.CancelTransaction(transaction);
            _accountDb.SaveChanges();

            _transactionDb.Transactions.Remove(transaction);
            _transactionDb.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            _transactionDb.Dispose();
            _accountDb.Dispose();
            _categoryDb.Dispose();
            base.Dispose(disposing);
        }
    }
}